do

Event = {}

function Event:New()
    local event = {}
    setmetatable(event, self)
    self.__index = self
    self.__call = self.Call
    return event
end

function Event:Add(source, func)
    table.insert(self, {source, func})
end

function Event.Call(self, ...)
    for _, item in ipairs(self) do
        item[2](item[1], unpack(arg))
    end
end

Window = {
    Name = "Kidxu's Window"
}

function Window:Init()
    Button.ClickEvent:Add(self, self.Button_OnClick)
end

function Window:Button_OnClick(sender)
    print(sender.Name .. " Click On " .. self.Name)
end

Button = {
    Name = "A Button",
    ClickEvent = Event:New()
}

function Button:Click()
    print('Click begin')
    self.ClickEvent(self)
    print('Click end')
end

Window:Init()
Button:Click()

end
